package com.lz.autotest.project.testmanage.infmanage.service.impl;

import com.lz.autotest.common.aspectj.lang.annotation.DataScope;
import com.lz.autotest.common.constant.UserConstants;
import com.lz.autotest.common.utils.DateUtils;
import com.lz.autotest.project.system.domain.SysUser;
import com.lz.autotest.common.text.Convert;
import com.lz.autotest.common.utils.SecurityUtils;
import com.lz.autotest.common.utils.StringUtils;
import com.lz.autotest.common.utils.spring.SpringUtils;
import com.lz.autotest.common.web.domain.TreeSelect;
import com.lz.autotest.project.testmanage.infmanage.domain.SstInf;
import com.lz.autotest.project.testmanage.infmanage.mapper.InfManageMapper;
import com.lz.autotest.project.testmanage.infmanage.service.InfManageService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 接口管理 服务实现
 *
 * @author lz
 */
@Service
public class InfManageServiceImpl implements InfManageService {

    @Resource
    private InfManageMapper infManageMapper;

    /**
     * 查询接口管理数据
     *
     * @param sstInf 接口信息
     * @return 接口信息集合
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<SstInf> selectSstInfList(SstInf sstInf) {
        return infManageMapper.selectSstInfList(sstInf);
    }

    @Override
    public List<SstInf> selectSstInfListByCondition(SstInf sstInf) {
        return infManageMapper.selectSstInfListByCondition(sstInf);
    }

    @Override
    public List<Map<String, Object>> queryInfAll(SstInf sstInf) {
        return infManageMapper.queryInfAll(sstInf);
    }

    @Override
    public List<Map<String, Object>> querySstInfAll(Map map) {
        return infManageMapper.querySstInfAllList(map);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param sstInfs 接口列表
     * @return 树结构列表
     */
    @Override
    public List<SstInf> buildSstInfTree(List<SstInf> sstInfs) {
        List<SstInf> returnList = new ArrayList<SstInf>();
        List<String> tempList = new ArrayList<String>();
        for (SstInf dept : sstInfs) {
            tempList.add(dept.getInfId());
        }
        for (Iterator<SstInf> iterator = sstInfs.iterator(); iterator.hasNext(); ) {
            SstInf dept = (SstInf) iterator.next();
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(dept.getParentId())) {
                recursionFn(sstInfs, dept);
                returnList.add(dept);
            }
        }
        if (returnList.isEmpty()) {
            returnList = sstInfs;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param sstInfs 接口列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildSstInfTreeSelect(List<SstInf> sstInfs) {
        List<SstInf> deptTrees = buildSstInfTree(sstInfs);
        return deptTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }


    /**
     * 根据接口ID查询信息
     *
     * @param infId 接口ID
     * @return 接口信息
     */
    @Override
    public SstInf selectSstInfById(String infId) {
        return infManageMapper.selectSstInfById(infId);
    }

    /**
     * 根据ID查询所有子接口（正常状态）
     *
     * @param infId 接口ID
     * @return 子接口数
     */
    @Override
    public int selectNormalChildrenSstInfById(String infId) {
        return infManageMapper.selectNormalChildrenSstInfById(infId);
    }

    /**
     * 是否存在子节点
     *
     * @param infId 接口ID
     * @return 结果
     */
    @Override
    public boolean hasChildBySstInfId(String infId) {
        int result = infManageMapper.hasChildBySstInfId(infId);
        return result > 0 ? true : false;
    }


    /**
     * 校验接口名称是否唯一
     *
     * @param sstInf 接口信息
     * @return 结果
     */
    @Override
    public String checkSstInfNameUnique(SstInf sstInf) {
        String deptId = StringUtils.isNull(sstInf.getInfId()) ? "-1" : sstInf.getInfId();
        SstInf info = infManageMapper.checkSstInfNameUnique(sstInf.getInfName(), sstInf.getParentId());
        if (StringUtils.isNotNull(info) && !info.getInfId().equals(deptId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public String checkSstInfCodeUnique(SstInf sstInf) {
        String deptId = StringUtils.isNull(sstInf.getInfId()) ? "-1" : sstInf.getInfId();
        SstInf info = infManageMapper.checkSstInfCodeUnique(sstInf.getInfCode(), sstInf.getParentId());
        if (StringUtils.isNotNull(info) && !info.getInfId().equals(deptId)) {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 校验接口是否有数据权限
     *
     * @param infId 接口id
     */
    @Override
    public void checkSstInfDataScope(String infId) {
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            SstInf dept = new SstInf();
            dept.setInfId(infId);
            List<SstInf> sstInfs = SpringUtils.getAopProxy(this).selectSstInfList(dept);
            if (StringUtils.isEmpty(sstInfs)) {
                throw new com.lz.autotest.common.exception.ServiceException("没有权限访问接口数据！");
            }
        }
    }

    /**
     * 新增保存接口信息
     *
     * @param sstInf 接口信息
     * @return 结果
     */
    @Override
    public int insertSstInf(SstInf sstInf) {
        SstInf info = infManageMapper.selectSstInfById(sstInf.getParentId());
        // 如果父节点不为正常状态,则不允许新增子节点
        if (!UserConstants.DEPT_NORMAL.equals(info.getStatus())) {
            throw new com.lz.autotest.common.exception.ServiceException("接口停用，不允许新增");
        }
        sstInf.setAncestors(info.getAncestors() + "," + sstInf.getParentId());
        return infManageMapper.insertSstInf(sstInf);
    }

    /**
     * 修改保存接口信息s
     *
     * @param sstInf 接口信息
     * @return 结果
     */
    @Override
    public int updateSstInf(SstInf sstInf) {
        sstInf.setUpdateTime(DateUtils.getCurr_YYYY_MM_DD_HH_MM_SS());
        SstInf newParentSstInf = infManageMapper.selectSstInfById(sstInf.getParentId());
        SstInf oldSstInf = infManageMapper.selectSstInfById(sstInf.getInfId());
        if (StringUtils.isNotNull(newParentSstInf) && StringUtils.isNotNull(oldSstInf)) {
            String newAncestors = newParentSstInf.getAncestors() + "," + newParentSstInf.getInfId();
            String oldAncestors = oldSstInf.getAncestors();
            sstInf.setAncestors(newAncestors);
            updateSstInfChildren(sstInf.getInfId(), newAncestors, oldAncestors);
        }
        int result = infManageMapper.updateSstInf(sstInf);
        if (UserConstants.DEPT_NORMAL.equals(sstInf.getStatus()) && StringUtils.isNotEmpty(sstInf.getAncestors())
                && !StringUtils.equals("0", sstInf.getAncestors())) {
            // 如果该接口是启用状态，则启用该接口的所有上级接口
            updateParentSstInfStatusNormal(sstInf);
        }
        return result;
    }

    /**
     * 修改该接口的父级接口状态
     *
     * @param sstInf 当前接口
     */
    private void updateParentSstInfStatusNormal(SstInf sstInf) {
        String ancestors = sstInf.getAncestors();
        String[] deptIds = Convert.toStrArray(ancestors);
        infManageMapper.updateSstInfStatusNormal(deptIds);
    }

    /**
     * 修改子元素关系
     *
     * @param deptId       被修改的接口ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateSstInfChildren(String deptId, String newAncestors, String oldAncestors) {
        List<SstInf> children = infManageMapper.selectChildrenSstInfById(deptId);
        for (SstInf child : children) {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (!children.isEmpty()) {
            infManageMapper.updateSstInfChildren(children);
        }
    }

    /**
     * 删除接口管理信息
     *
     * @param deptId 接口ID
     * @return 结果
     */
    @Override
    public int deleteSstInfById(String deptId) {
        return infManageMapper.deleteSstInfById(deptId);
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<SstInf> list, SstInf t) {
        // 得到子节点列表
        List<SstInf> childList = getChildList(list, t);
        t.setChildren(childList);
        for (SstInf tChild : childList) {
            if (hasChild(list, tChild)) {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<SstInf> getChildList(List<SstInf> list, SstInf t) {
        List<SstInf> tlist = new ArrayList<SstInf>();
        for (SstInf n : list) {
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId().equals(t.getInfId())) {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<SstInf> list, SstInf t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }

    @Override
    public List<TreeSelect> selectSstInfTreeList(SstInf dept) {
        List<SstInf> depts = SpringUtils.getAopProxy(this).selectSstInfList(dept);
        return buildSstInfTreeSelect(depts);
    }

    @Override
    public Map<String,String> countInf() {
        Map<String,String> map = infManageMapper.countInf();
        return map;
    }

    @Override
    public List<SstInf> childrenList(String infId) {
        return infManageMapper.childrenList(infId);
    }

    @Override
    public List<SstInf> selectInfListByIds(List<String> list) {
        return infManageMapper.selectInfListByIds(list);
    }
}
